﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Transcend.DP3.Helper
{

	public class TypeHelper
	{

		/// <summary>
		/// 尝试类型转换，转换不成功不报错
		/// </summary>
		public static T Try<T>(object val, T defValue = default(T))
		{
			try
			{
				return Change<T>(val, defValue);
			}
			catch
			{
				return defValue;
			}
		}

		/// <summary>
		/// 类型转换，转换不成功报错
		/// </summary>
		public static T Change<T>(object val, T defValue = default(T))
		{
			var target = defValue;

			// 如果是空值则不进行转换
			if (val == null || val == DBNull.Value) return defValue;

			var type = typeof(T);
			var underlyingType = Nullable.GetUnderlyingType(type);
			if (underlyingType == null) underlyingType = type;

			switch (Type.GetTypeCode(underlyingType))
			{
				case TypeCode.Byte:
				case TypeCode.Char:
				case TypeCode.Decimal:
				case TypeCode.Double:
				case TypeCode.Int16:
				case TypeCode.Int32:
				case TypeCode.Int64:
				case TypeCode.SByte:
				case TypeCode.Single:
				case TypeCode.UInt16:
				case TypeCode.UInt32:
				case TypeCode.UInt64:
				case TypeCode.Boolean:
				case TypeCode.String:
				case TypeCode.DateTime:
					target = (T)System.Convert.ChangeType(val, underlyingType);
					break;
				case TypeCode.Empty:
				case TypeCode.DBNull:
					break;
				case TypeCode.Object:
				default:
					throw new ArgumentException(string.Format("无法将值{0}转换成类型{1}", val, type));
			}
			return target;
		}

		/// <summary>
		/// 判断对象类型是否为数字类型，包括[sbyte,byte,short,ushort,int,unit,long,ulong,float,double,decimal]
		/// </summary>
		public static bool IsNumber(object oval)
		{
			return oval is sbyte
			|| oval is byte
			|| oval is short
			|| oval is ushort
			|| oval is int
			|| oval is uint
			|| oval is long
			|| oval is ulong
			|| oval is float
			|| oval is double
			|| oval is decimal;
		}

	}
}
